#include "mainwindow.h"
#include "ui_mainwindow.h"

QSerialPort myserial;
uint8 frame_buffer[300];
QTimer *timer_serial_rece_timeout;//串口接收断帧

QByteArray rece_frame;
QSqlTableModel *model;
Dlg_SelectDid *dlg_select_did;


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QObject::connect(&myserial,&QSerialPort::readyRead,this,&MainWindow::on_serial_receive_data);
    timer_serial_rece_timeout = new QTimer(this);
    QObject::connect(timer_serial_rece_timeout,SIGNAL(timeout()),this,SLOT(on_timer_serial_rece_timeout()));


    if ( !createConnection() )
        qDebug()<<"数据库连接->失败";
    else
        qDebug()<<"数据库连接->成功";

    model = new QSqlTableModel;
    model->setTable("student");//model绑定到db库的student表
    model->setSort(1, Qt::AscendingOrder);
    model->setHeaderData(1, Qt::Horizontal, "Name");
    model->setHeaderData(2, Qt::Horizontal, "Age");
    model->select();

    ui->tableView->setModel(model);//视图与tableView绑定
    ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
    ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);//按行选择
    ui->tableView->resizeColumnsToContents();
    ui->tableView->setEditTriggers(QAbstractItemView::DoubleClicked);//双击编辑
    dlg_select_did = new Dlg_SelectDid(this);





    ui->comboBoxDataBits->setCurrentText("8");
    ui->comboBoxBaud->setCurrentText("9600");
    ui->lineEditDID->setMaxLength(4);
    ui->lineEdit645DID->setMaxLength(8);
    ui->lineEdit645Len->setEnabled(false);
    ui->tableWidgetDisp->setColumnWidth(0,40);
    ui->tableWidgetDisp->setColumnWidth(1,100);
    ui->tableWidgetDisp->horizontalHeader()->setStretchLastSection(true);//关键




    on_pushButtonScan_clicked();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_serial_receive_data()
{
    QByteArray dataArray;
    dataArray = myserial.readAll();//读取数据
    rece_frame += dataArray;//rece_frame收完一帧数据后会被清空
    ui->textEditRece->insertPlainText(dataArray.toHex().toUpper()+" ");
    QTextCursor cursor=ui->textEditRece->textCursor();
    cursor.movePosition(QTextCursor::End); //保持编辑器在光标最后一行
    ui->textEditRece->setTextCursor(cursor);
    timer_serial_rece_timeout->start(20);//20ms断帧
}

void MainWindow::serial_ui_init()
{

}
void MainWindow::on_pushButtonScan_clicked()
{
    ui->comboBox_portName->clear();
    ui->textEditRece->append("共扫描到 "
                              + QString::number(QSerialPortInfo::availablePorts().count())
                              + " 个可用串口：");


    foreach( const QSerialPortInfo &Info,QSerialPortInfo::availablePorts())//读取串口信息
    {
        qDebug() << "portName    :"  << Info.portName();//调试时可以看的串口信息
        qDebug() << "Description   :" << Info.description();
        qDebug() << "Manufacturer:" << Info.manufacturer();

        ui->textEditRece->append(Info.portName() +"  "+ Info.description());
        QSerialPort serial;
        serial.setPort(Info);
        ui->comboBox_portName->addItem( Info.portName()  );//在comboBox那添加串口号
    }
    ui->textEditRece->append("\r\n");
}

void MainWindow::on_pushButtonOpenSerial_clicked()
{
    myserial.setPortName(ui->comboBox_portName->currentText());//combo中选定的串口号
    myserial.setBaudRate((ui->comboBoxBaud->currentText()).toInt());
    myserial.setDataBits((enum QSerialPort::DataBits)(ui->comboBoxDataBits->currentText().toInt()));
    switch(ui->comboBoxStopBits->currentText().toInt())
    {
        case 1: myserial.setStopBits(QSerialPort::OneStop);break;
        case 3: myserial.setStopBits(QSerialPort::OneAndHalfStop);break;
        case 2: myserial.setStopBits(QSerialPort::TwoStop);break;
        default:qDebug()<<"停止位错误"; return;
    }
    switch(ui->comboBoxParity->currentIndex())
    {
        case 0: myserial.setParity(QSerialPort::NoParity);break;
        case 1: myserial.setParity(QSerialPort::OddParity);break;
        case 2: myserial.setParity(QSerialPort::EvenParity);break;
        default:qDebug()<<"校验位错误"; return;
    }

    myserial.setFlowControl(QSerialPort::NoFlowControl);//流控制

    if( myserial.isOpen() )
        myserial.close();
    else
        myserial.open(QIODevice::ReadWrite);//打开串口

    if( myserial.isOpen() )
    {
        ui->pushButtonOpenSerial->setIcon(QIcon(":/image/serial_opened_icon"));
        ui->pushButtonOpenSerial->setText("关闭串口");
    }
    else
    {
        ui->pushButtonOpenSerial->setIcon(QIcon(":/image/serial_closed_icon"));
        ui->pushButtonOpenSerial->setText("打开串口");
    }

    if(myserial.error())
    {
        QMessageBox::information(this, tr("提示"), tr("操作失败(可能该串口正在被其他软件占用)，请检查或者重启本软件！"));
        qDebug()<<"串口打开失败，原因是："<<myserial.error();
        myserial.clearError();
    }
}

void MainWindow::on_pushButtonSend_clicked()
{
    if( myserial.isOpen() )
    {       
        bool ok;
        struct SHS_frame *pframe = (struct SHS_frame*)frame_buffer;
        pframe->stc = 0x7E;
        *(quint32 *)pframe->said  = ui->lineEditSaid->text().toInt();
        *(quint32 *)pframe->taid  = ui->lineEditTaid->text().toInt();
        static uint8 seq_tmp=0;
        pframe->seq = seq_tmp++;

        struct FBD_Frame *pFBD = (struct FBD_Frame *)pframe->infor;
        if(ui->comboBoxCMD->currentText() == "读-02H")
            pFBD->cmd = 0x02;
        else if(ui->comboBoxCMD->currentText() == "写-07H")
            pFBD->cmd = 0x07;

        pFBD->did[0] =  ui->lineEditDID->text().right(2).toInt(&ok, 16);
        pFBD->did[1] =  ui->lineEditDID->text().left(2).toInt(&ok, 16);

        QStringList sl = ui->lineEditData->text().split(" ", QString::SkipEmptyParts);
        int i=0;
        foreach (QString str, sl)
        {

           pFBD->data[i++] =  str.toInt(&ok, 16);
           if((!ok) || (str.count()!=2))
           {
                QMessageBox::information(this, tr("错误提示"), QString("填入的7E->data域内容格式有误！可能的原因：\r\n")
                                                            + QString("1、两个字节之间没有用空格隔开\r\n")
                                                            + QString("2、包含了非法(非HEX)字符"));
                return;
           }
        }

        pFBD->ctrl = sl.count();
        pframe->length = 4+pFBD->ctrl;//DID+CTRL+DATA
        pframe->infor[pframe->length] = checksum(frame_buffer, SHS_FRAME_HEAD+pframe->length);


        int rowCount = ui->tableWidgetDisp->rowCount();
        ui->tableWidgetDisp->setRowCount(rowCount+1);
        rowCount = ui->tableWidgetDisp->rowCount();

        QByteArray byte = QByteArray((const char *)frame_buffer,SHS_FRAME_HEAD+pframe->length+1);//数组转QByteArray类
        QString str = byte_num_to_hex_string_with_space(byte);
        ui->tableWidgetDisp->setItem(rowCount-1, 1, new QTableWidgetItem(str));
        ui->tableWidgetDisp->setItem(rowCount-1, 0, new QTableWidgetItem(QString("发送")));
        ui->tableWidgetDisp->setCurrentCell(rowCount-1,1);//移动光标
        myserial.write((const char *)frame_buffer,SHS_FRAME_HEAD+pframe->length+1);

    }
    else
    {
        ui->textEditRece->append("串口未打开！");
    }

}

void MainWindow::on_pushButton_clicked()
{
    ui->textEditRece->setText("");
}

void MainWindow::on_timer_serial_rece_timeout()
{
    timer_serial_rece_timeout->stop();

    int rowCount = ui->tableWidgetDisp->rowCount();
    ui->tableWidgetDisp->setRowCount(rowCount+1);
    rowCount = ui->tableWidgetDisp->rowCount();

    QString str = byte_num_to_hex_string_with_space(rece_frame);
    ui->tableWidgetDisp->setItem(rowCount-1, 1, new QTableWidgetItem(str));
    ui->tableWidgetDisp->setItem(rowCount-1, 0, new QTableWidgetItem(QString("接收")));
    ui->tableWidgetDisp->setCurrentCell(rowCount-1,1);//移动光标
    rece_frame.clear();
    qDebug()<<"断帧";
}



void MainWindow::on_pushButtonClrTable_clicked()
{
    int rowCount=ui->tableWidgetDisp->rowCount();
    while(rowCount)
        ui->tableWidgetDisp->removeRow((rowCount--)-1);
}



void MainWindow::on_pushButtonSelectDid_clicked()
{
    dlg_select_did->exec();
}
